/*
 * windowstore.cpp - class that maintains list of windows/tabs
 * Copyright (C) 2009  Sergei Stolyarov
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * Kajim::ChatInputText widget implements basic functions required
 * by chat text entry widget: history navigation, autocompletion etc
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <QtGui>

#include "windowstore.h"
#include "widgets/contentcontainerwidget.h"
#include "rosterwindow.h"
#include "constants.h"
#include "settings.h"
#include "advdialog.h"

struct Kajim::WindowStore::Private
{
    QMap<Common::ContentContainerWidget*, QWidget*> containers; //! key is content container widget, value is window/tab widget
    RosterWindow * rosterWindowWidget;
    QTabWidget * allChatsTabWidget;
    QDialog * allChatsTabWidgetDialog;
    QString layout;
};

Kajim::WindowStore::~WindowStore()
{
    delete d;
}

Kajim::WindowStore * Kajim::WindowStore::instance()
{
    if (Kajim::WindowStore::inst == 0) {
        Kajim::WindowStore::inst = new Kajim::WindowStore();
    }

    return Kajim::WindowStore::inst;
}

QWidget * Kajim::WindowStore::chatWindow(Kajim::Common::ContentContainerWidget * chat)
{
    if (!d->containers.contains(chat)) {
        qDebug() << ">> creating new chat window";
        // create corresponding element
        QWidget * window = createContentContainer(chat);
        if (window != 0) {
            window->show();
        }
    }
    return d->containers[chat];
}

RosterWindow * Kajim::WindowStore::rosterWindow()
{
    if (d->rosterWindowWidget == 0) {
        d->rosterWindowWidget = new RosterWindow();
    }

    return d->rosterWindowWidget;
}

void Kajim::WindowStore::updateLayout()
{
    QString new_layout = Kajim::Settings::get("ui/layout").toString();
    if (d->layout != new_layout) {
        qDebug() << "Kajim::WindowStore::updateLayout() called";

        if (new_layout == Kajim::Ui::LAYOUT_SINGLE_WINDOW) {
            // create tab widget
            qDebug() << "create QTabWidget for single window";
            QTabWidget * tabs = new QTabWidget();
            d->rosterWindowWidget->addTabsWidget(tabs);
        } else if (new_layout == Kajim::Ui::LAYOUT_ROSTER_AND_SINGLE_CHAT) {
            // TODO: create allChatsTabWidget and allChatsTabWidgetDialog
        }
        // remember content containers
        QMap<Kajim::Common::ContentContainerWidget*, QWidget*> r_containers = d->containers;

        // recreate content containers
        Q_FOREACH(Kajim::Common::ContentContainerWidget * cw, d->containers.keys()) {
            QWidget * w = createContentContainer(cw);
            if (w != 0) {
                w->show();
            }
        }

        if (Kajim::Ui::LAYOUT_MULTIPLE_WINDOWS == d->layout) {
            // destroy all content windows
            Q_FOREACH(Kajim::Common::ContentContainerWidget * cw, d->containers.keys()) {
                if (r_containers.contains(cw)) {
                    delete r_containers[cw];
                }
            }
        } else if (Kajim::Ui::LAYOUT_SINGLE_WINDOW == d->layout) {
            // move allChatsTabWidget into the separate window
            d->rosterWindowWidget->removeTabsWidget();
        } else if (Kajim::Ui::LAYOUT_ROSTER_AND_SINGLE_CHAT == d->layout) {
            delete d->allChatsTabWidget;
            d->allChatsTabWidget = 0;
            delete d->allChatsTabWidgetDialog;
            d->allChatsTabWidgetDialog = 0;
        }

        d->layout = new_layout;
    }
}

QWidget * Kajim::WindowStore::createContentContainer(Kajim::Common::ContentContainerWidget * content)
{
    QString layout_mode = Kajim::Settings::get("ui/layout").toString();
    QWidget * w = 0;

    if (Kajim::Ui::LAYOUT_MULTIPLE_WINDOWS == layout_mode) {
        qDebug() << "create window container";
        w = new Kajim::Common::AdvDialog();
        // TODO: add program name to the title?
        w->setWindowTitle(content->title());
        connect(w, SIGNAL(dialogClosed()), this, SLOT(dialogClose()));
        QVBoxLayout *layout = new QVBoxLayout(w);
        w->setLayout(layout);
        content->setParent(w);
        content->show();
        layout->addWidget(content);

    } else if (Kajim::Ui::LAYOUT_ROSTER_AND_SINGLE_CHAT == layout_mode) {
        qDebug() << "create tab container";
        // create chat in the tabs widget with all chats
        content->setParent(d->allChatsTabWidget);
        d->allChatsTabWidget->addTab(content, "zzz");
        w = 0;

    } else if (Kajim::Ui::LAYOUT_SINGLE_WINDOW == layout_mode) {
        qDebug() << "create tab in the single window";
        QTabWidget * tabs = d->rosterWindowWidget->tabsWidget();
        if (tabs != 0) {
            tabs->addTab(content, content->title());
        }
        w = 0;
    }

    d->containers[content] = w;

    return w;
}

void Kajim::WindowStore::dialogClose()
{
    QObject * sender = this->sender();

    if (sender == 0) {
        return;
    }

    // destroy closed window
    Kajim::Common::ContentContainerWidget * k = d->containers.key(static_cast<QWidget*>(sender));
    if (k != 0) {
        delete sender;
        // remove item from map
        d->containers.remove(k);
    }
}

Kajim::WindowStore::WindowStore(QObject * parent)
    : QObject(parent)
{
    d = new Private;
    d->allChatsTabWidget = 0;
    d->allChatsTabWidgetDialog = 0;
    d->rosterWindowWidget = 0;

    d->layout = ""; //Kajim::Settings::get("ui/layout").toString();
}

Kajim::WindowStore * Kajim::WindowStore::inst = 0;
